home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 726-750 / 745 / arexxbox / test / rx_test.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  17KB  |  927 lines

  1. /*
  2.  * Source generated with ARexxBox 1.00 (Jun 19 1992)
  3.  * which is Copyright (c) 1992 Michael Balzer
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <rexx/storage.h>
  10. #include <rexx/rxslib.h>
  11.  
  12. #ifdef __GNUC__
  13. /* GCC needs all struct defs */
  14. #include <dos/exall.h>
  15. #include <graphics/graphint.h>
  16. #include <intuition/classes.h>
  17. #include <devices/keymap.h>
  18. #include <exec/semaphores.h>
  19. #endif
  20.  
  21. #include <clib/alib_protos.h>
  22. #include <clib/exec_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/rexxsyslib_protos.h>
  25.  
  26. #ifndef __NO_PRAGMAS
  27.  
  28. #ifdef AZTEC_C
  29. #include <pragmas/exec_lib.h>
  30. #include <pragmas/dos_lib.h>
  31. #include <pragmas/rexxsyslib_lib.h>
  32. #endif
  33.  
  34. #ifdef LATTICE
  35. #include <pragmas/exec_pragmas.h>
  36. #include <pragmas/dos_pragmas.h>
  37. #include <pragmas/rexxsyslib_pragmas.h>
  38. #endif
  39.  
  40. #endif /* __NO_PRAGMAS */
  41.  
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46.  
  47. #ifndef _toupper
  48. #define _toupper(x) ((x) & 0x5f)
  49. #endif
  50.  
  51. #include <dos/rdargs.h>
  52.  
  53. #define NO_GLOBALS
  54. #include "rx_test.h"
  55.  
  56. struct rxs_stemnode
  57. {
  58.     struct rxs_stemnode *succ;
  59.     char *name;
  60.     char *value;
  61. };
  62.  
  63.  
  64. extern struct Library *SysBase, *DOSBase, *RexxSysBase;
  65.  
  66. char RexxPortBaseName[80] = "arbtest";
  67.  
  68. struct rxs_command rxs_commandlist[] =
  69. {
  70.     { "HELP", "COMMAND,PROMPT/S", "COMMANDDESC,COMMANDLIST/M", RESINDEX(rxd_help), rx_help, 1 },
  71.     { "INOUT", "ARG1/N", "RES1", RESINDEX(rxd_inout), rx_inout, 1 },
  72.     { "MULTI_IN_NUM", "LISTE/N/M", NULL, 0, rx_multi_in_num, 1 },
  73.     { "MULTI_IN_STR", "LISTE/M", NULL, 0, rx_multi_in_str, 1 },
  74.     { "MULTI_OUT_NUM", NULL, "LISTE/N/M", RESINDEX(rxd_multi_out_num), rx_multi_out_num, 1 },
  75.     { "MULTI_OUT_STR", NULL, "LISTE/M", RESINDEX(rxd_multi_out_str), rx_multi_out_str, 1 },
  76.     { "OPEN", "FILE/K,PROMPT/S", NULL, 0, rx_open, 1 },
  77.     { NULL, NULL, NULL, NULL, NULL }
  78. };
  79.  
  80.  
  81. void ReplyRexxCommand(
  82.     struct RexxMsg    *rexxmessage,
  83.     long            primary,
  84.     long            secondary,
  85.     char            *result )
  86. {
  87.     if( rexxmessage->rm_Action & RXFF_RESULT )
  88.     {
  89.         if( primary == 0 )
  90.         {
  91.             secondary = result
  92.                 ? (long) CreateArgstring( result, strlen(result) )
  93.                 : (long) NULL;
  94.         }
  95.         else
  96.         {
  97.             char buf[16];
  98.             
  99.             if( primary > 0 )
  100.             {
  101.                 sprintf( buf, "%ld", secondary );
  102.                 result = buf;
  103.             }
  104.             else
  105.             {
  106.                 primary = -primary;
  107.                 result = (char *) secondary;
  108.             }
  109.             
  110.             SetRexxVar( (struct Message *) rexxmessage,
  111.                 "RC2", result, strlen(result) );
  112.             
  113.             secondary = 0;
  114.         }
  115.     }
  116.     else if( primary < 0 )
  117.         primary = -primary;
  118.     
  119.     rexxmessage->rm_Result1 = primary;
  120.     rexxmessage->rm_Result2 = secondary;
  121.     ReplyMsg( (struct Message *) rexxmessage );
  122. }
  123.  
  124.  
  125. void FreeRexxCommand( struct RexxMsg *rexxmessage )
  126. {
  127.     if( !rexxmessage->rm_Result1 && rexxmessage->rm_Result2 )
  128.         DeleteArgstring( (char *) rexxmessage->rm_Result2 );
  129.  
  130.     if( rexxmessage->rm_Stdin )
  131.         Close( rexxmessage->rm_Stdin );
  132.  
  133.     if( rexxmessage->rm_Stdout &&
  134.         rexxmessage->rm_Stdout != rexxmessage->rm_Stdin )
  135.         Close( rexxmessage->rm_Stdout );
  136.  
  137.     DeleteArgstring( (char *) ARG0(rexxmessage) );
  138.     DeleteRexxMsg( rexxmessage );
  139. }
  140.  
  141.  
  142. struct RexxMsg *SendRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  143. {
  144.     struct MsgPort *rexxport;
  145.     struct RexxMsg *rexx_command_message;
  146.  
  147.     Forbid();
  148.  
  149.     if( (rexxport = FindPort(RXSDIR)) == NULL )
  150.     {
  151.         Permit();
  152.         return( NULL );
  153.     }
  154.  
  155.     if( (rexx_command_message = CreateRexxMsg( host->port,
  156.         REXX_EXTENSION, host->port->mp_Node.ln_Name)) == NULL )
  157.     {
  158.         Permit();
  159.         return( NULL );
  160.     }
  161.  
  162.     if( (rexx_command_message->rm_Args[0] =
  163.         CreateArgstring(buff,strlen(buff))) == NULL )
  164.     {
  165.         DeleteRexxMsg(rexx_command_message);
  166.         Permit();
  167.         return( NULL );
  168.     }
  169.  
  170.     rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  171.     rexx_command_message->rm_Stdin  = fh;
  172.     rexx_command_message->rm_Stdout = fh;
  173.     
  174.     PutMsg( rexxport, &rexx_command_message->rm_Node );
  175.     Permit();
  176.     
  177.     ++host->replies;
  178.     return( rexx_command_message );
  179. }
  180.  
  181.  
  182. void CloseDownARexxHost( struct RexxHost *host )
  183. {
  184.     struct RexxMsg *rexxmsg;
  185.  
  186.     while( host->replies > 0 )
  187.     {
  188.         WaitPort( host->port );
  189.         
  190.         while( rexxmsg = (struct RexxMsg *)GetMsg(host->port) )
  191.         {
  192.             if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  193.             {
  194.                 FreeRexxCommand( rexxmsg );
  195.                 --host->replies;
  196.             }
  197.             else
  198.                 ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  199.         }
  200.     }
  201.     
  202.     if( host->rdargs ) FreeDosObject( DOS_RDARGS, host->rdargs );
  203.     if( host->port ) DeletePort( host->port );
  204.     free( host );
  205. }
  206.  
  207.  
  208. struct RexxHost *SetupARexxHost( char *basename )
  209. {
  210.     struct RexxHost *host;
  211.     int ext = 0;
  212.     
  213.     if( !(host = calloc(sizeof *host, 1)) )
  214.         return NULL;
  215.     
  216.     if( !basename )
  217.         basename = RexxPortBaseName;
  218.     
  219.     strcpy( host->portname, basename );
  220.     
  221.     if( !host->portname[0] )
  222.     {
  223.         free( host );
  224.         return NULL;
  225.     }
  226.     
  227.     while( FindPort(host->portname) )
  228.         sprintf( host->portname, "%s.%d", basename, ++ext );
  229.     
  230.     if( !(host->port = CreatePort(host->portname, 0)) )
  231.     {
  232.         free( host );
  233.         return NULL;
  234.     }
  235.     
  236.     if( !(host->rdargs = AllocDosObject(DOS_RDARGS, NULL)) )
  237.     {
  238.         DeletePort( host->port );
  239.         free( host );
  240.         return NULL;
  241.     }
  242.     
  243.     host->rdargs->RDA_Flags = RDAF_NOPROMPT;
  244.     
  245.     return( host );
  246. }
  247.  
  248.  
  249. struct rxs_command *FindRXCommand( char *com )
  250. {
  251.     struct rxs_command *rxc = rxs_commandlist;
  252.     int n = strlen( com );
  253.     
  254.     while( rxc->command )
  255.     {
  256.         if( strnicmp(com, rxc->command, n) == 0 )
  257.             break;
  258.         rxc++;
  259.     }
  260.     
  261.     if( rxc->command )
  262.         return( rxc );
  263.     else
  264.         return( NULL );
  265. }
  266.  
  267.  
  268. static struct rxs_command *ParseRXCommand( char **arg )
  269. {
  270.     char com[256], *s, *t;
  271.     
  272.     s = *arg;
  273.     t = com;
  274.     
  275.     while( *s && *s != ' ' && *s != '\n' )
  276.         *t++ = *s++;
  277.     
  278.     *t = '\0';
  279.     while( *s == ' ' ) ++s;
  280.     *arg = s;
  281.     
  282.     return( FindRXCommand( com ) );
  283. }
  284.  
  285.  
  286. static char *CreateVAR( struct rxs_stemnode *stem )
  287. {
  288.     char *var;
  289.     struct rxs_stemnode *s;
  290.     long size = 0;
  291.     
  292.     if( !stem || stem == (struct rxs_stemnode *) -1L )
  293.         return( (char *) stem );
  294.     
  295.     for( s = stem; s; s = s->succ )
  296.         size += strlen( s->value ) + 1;
  297.     
  298.     var = malloc( size + 1 );
  299.     *var = '\0';
  300.     
  301.     for( s = stem; s; s = s->succ )
  302.     {
  303.         strcat( var, s->value );
  304.         if( s->succ )
  305.             strcat( var, " " );
  306.     }
  307.     
  308.     return( var );
  309. }
  310.  
  311.  
  312. static struct rxs_stemnode *new_stemnode( struct rxs_stemnode **first, struct rxs_stemnode **old )
  313. {
  314.     struct rxs_stemnode *new;
  315.     
  316.     if( !(new = calloc(sizeof(struct rxs_stemnode), 1)) )
  317.     {
  318.         return( NULL );
  319.     }
  320.     else
  321.     {
  322.         if( *old )
  323.         {
  324.             (*old)->succ = new;
  325.             (*old) = new;
  326.         }
  327.         else
  328.         {
  329.             *first = *old = new;
  330.         }
  331.     }
  332.     
  333.     return( new );
  334. }
  335.  
  336.  
  337. static void free_stemlist( struct rxs_stemnode *first )
  338. {
  339.     struct rxs_stemnode *next;
  340.     
  341.     for( ; first; first = next )
  342.     {
  343.         next = first->succ;
  344.         free( first->name );
  345.         free( first->value );
  346.         free( first );
  347.     }
  348. }
  349.  
  350.  
  351. static struct rxs_stemnode *CreateSTEM( struct rxs_command *rxc, LONG *resarray, char *stembase )
  352. {
  353.     struct rxs_stemnode *first = NULL, *old = NULL, *new;
  354.     char resb[512], *rs, *rb;
  355.     char longbuff[16];
  356.  
  357.     if( stembase )
  358.         strcpy( resb, stembase );
  359.     else
  360.         *resb = '\0';
  361.     
  362.     rb = resb + strlen(resb);
  363.     rs = rxc->results;
  364.     
  365.     while( *rs )
  366.     {
  367.         char *t = rb;
  368.         BOOL optn = FALSE, optm = FALSE;
  369.         
  370.         while( *rs && *rs != ',' )
  371.         {
  372.             if( *rs == '/' )
  373.             {
  374.                 ++rs;
  375.                 if( *rs == 'N' ) optn = TRUE;
  376.                 else if( *rs == 'M' ) optm = TRUE;
  377.             }
  378.             else
  379.                 *t++ = *rs;
  380.             
  381.             ++rs;
  382.         }
  383.         
  384.         if( *rs == ',' ) ++rs;
  385.         *t = '\0';
  386.         
  387.         /*
  388.          * Resultat(e) erzeugen
  389.          */
  390.         
  391.         if( !*resarray )
  392.         {
  393.             ++resarray;
  394.             continue;
  395.         }
  396.         
  397.         if( optm )
  398.         {
  399.             long *r, index = 0;
  400.             LONG **subarray = (LONG **) *resarray++;
  401.             struct rxs_stemnode *countnd;
  402.             
  403.             /* Anzahl der Elemente */
  404.             
  405.             if( !(new = new_stemnode(&first, &old)) )
  406.             {
  407.                 free_stemlist( first );
  408.                 return( (struct rxs_stemnode *) -1L );
  409.             }
  410.             countnd = new;
  411.             
  412.             /* Die Elemente selbst */
  413.             
  414.             while( r = *subarray++ )
  415.             {
  416.                 if( !(new = new_stemnode(&first, &old)) )
  417.                 {
  418.                     free_stemlist( first );
  419.                     return( (struct rxs_stemnode *) -1L );
  420.                 }
  421.                 
  422.                 sprintf( t, ".%ld", index++ );
  423.                 new->name = strdup( resb );
  424.                 
  425.                 if( optn )
  426.                 {
  427.                     sprintf( longbuff, "%ld", *r );
  428.                     new->value = strdup( longbuff );
  429.                 }
  430.                 else
  431.                 {
  432.                     new->value = strdup( (char *) r );
  433.                 }
  434.             }
  435.             
  436.             /* Die Count-Node */
  437.             
  438.             strcpy( t, ".COUNT" );
  439.             countnd->name = strdup( resb );
  440.             
  441.             sprintf( longbuff, "%ld", index );
  442.             countnd->value = strdup( longbuff );
  443.         }
  444.         else
  445.         {
  446.             /* Neue Node anlegen */
  447.             if( !(new = new_stemnode(&first, &old)) )
  448.             {
  449.                 free_stemlist( first );
  450.                 return( (struct rxs_stemnode *) -1L );
  451.             }
  452.             
  453.             new->name = strdup( resb );
  454.             
  455.             if( optn )
  456.             {
  457.                 sprintf( longbuff, "%ld", *((long *) *resarray) );
  458.                 new->value = strdup( longbuff );
  459.                 ++resarray;
  460.             }
  461.             else
  462.             {
  463.                 new->value = strdup( (char *) (*resarray++) );
  464.             }
  465.         }
  466.     }
  467.     
  468.     return( first );
  469. }
  470.  
  471.  
  472. static void DoRXCommand( struct RexxHost *host, struct RexxMsg *rexxmsg )
  473. {
  474.     struct rxs_command *rxc;
  475.     char *argb = NULL, *arg;
  476.     
  477.     LONG *array = NULL;
  478.     LONG *argarray;
  479.     LONG *resarray;
  480.     
  481.     char *cargstr = NULL;
  482.     long rc=20, rc2=0;
  483.     char *result = NULL;
  484.     
  485.     if( !(argb = malloc(strlen(ARG0(rexxmsg)) + 2)) )
  486.     {
  487.         rc2 = ERROR_NO_FREE_STORE;
  488.         goto drc_cleanup;
  489.     }
  490.     
  491.     /* welches Kommando? */
  492.     
  493.     strcpy( argb, ARG0(rexxmsg) );
  494.     strcat( argb, "\n" );
  495.     arg = argb;
  496.     
  497.     if( !( rxc = ParseRXCommand( &arg ) ) )
  498.     {
  499.         if( arg = ExpandRXCommand( host, ARG0(rexxmsg) ) )
  500.         {
  501.             free( argb );
  502.             if( !(argb = malloc( strlen(arg) + 2 )) )
  503.             {
  504.                 rc2 = ERROR_NO_FREE_STORE;
  505.                 goto drc_cleanup;
  506.             }
  507.             
  508.             strcpy( argb, arg );
  509.             strcat( argb, "\n" );
  510.             free( arg );
  511.             arg = argb;
  512.             
  513.             rxc = ParseRXCommand( &arg );
  514.         }
  515.     }
  516.     
  517.     if( !rxc )
  518.     {
  519.         rc2 = ERROR_NOT_IMPLEMENTED;
  520.         goto drc_cleanup;
  521.     }
  522.     
  523.     if( !(rxc->flags & ARB_CF_ENABLED) )
  524.     {
  525.         rc = -10;
  526.         rc2 = (long) "Command disabled";
  527.         goto drc_cleanup;
  528.     }
  529.     
  530.     /* Speicher für Argumente etc. holen */
  531.     
  532.     (rxc->function)( host, (void **) &array, RXIF_INIT );
  533.     cargstr = malloc( rxc->args ? 15+strlen(rxc->args) : 15 );
  534.     
  535.     if( !array || !cargstr )
  536.     {
  537.         rc2 = ERROR_NO_FREE_STORE;
  538.         goto drc_cleanup;
  539.     }
  540.     
  541.     argarray = array + 2;
  542.     resarray = array + rxc->resindex;
  543.     
  544.     /* Argumente parsen */
  545.     
  546.     if( rxc->results )
  547.         strcpy( cargstr, "VAR/K,STEM/K" );
  548.     else
  549.         *cargstr = '\0';
  550.     
  551.     if( rxc->args )
  552.     {
  553.         if( *cargstr )
  554.             strcat( cargstr, "," );
  555.         strcat( cargstr, rxc->args );
  556.     }
  557.     
  558.     if( *cargstr )
  559.     {
  560.         host->rdargs->RDA_Source.CS_Buffer = arg;
  561.         host->rdargs->RDA_Source.CS_Length = strlen(arg);
  562.         host->rdargs->RDA_Source.CS_CurChr = 0;
  563.         host->rdargs->RDA_DAList = NULL;
  564.         host->rdargs->RDA_Buffer = NULL;
  565.         
  566.         if( !ReadArgs(cargstr, argarray, host->rdargs) )
  567.         {
  568.             rc = 10;
  569.             rc2 = IoErr();
  570.             goto drc_cleanup;
  571.         }
  572.     }
  573.     
  574.     /* Funktion aufrufen */
  575.     
  576.     (rxc->function)( host, (void **) &array, RXIF_ACTION );
  577.     
  578.     rc = array[0];
  579.     rc2 = array[1];
  580.     
  581.     /* Resultat(e) auswerten */
  582.     
  583.     if( rxc->results && rc==0 &&
  584.         (rexxmsg->rm_Action & RXFF_RESULT) )
  585.     {
  586.         struct rxs_stemnode *stem, *s;
  587.         
  588.         stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  589.         result = CreateVAR( stem );
  590.         
  591.         if( result == (char *) -1 )
  592.         {
  593.             result = NULL;
  594.             rc = 20;
  595.             rc2 = ERROR_NO_FREE_STORE;
  596.         }
  597.         else if( result )
  598.         {
  599.             if( argarray[0] )
  600.             {
  601.                 /* VAR */
  602.                 
  603.                 if( SetRexxVar( (struct Message *) rexxmsg, (char *)argarray[0], result, strlen(result) ) )
  604.                 {
  605.                     rc = -10;
  606.                     rc2 = (long) "Unable to set Rexx variable";
  607.                 }
  608.                 
  609.                 free( result );
  610.                 result = NULL;
  611.             }
  612.             
  613.             if( argarray[1] )
  614.             {
  615.                 /* STEM */
  616.                 for( s = stem; s; s = s->succ )
  617.                     rc |= SetRexxVar( (struct Message *) rexxmsg, s->name, s->value, strlen(s->value) );
  618.                 
  619.                 if( rc )
  620.                 {
  621.                     rc = -10;
  622.                     rc2 = (long) "Unable to set Rexx variable";
  623.                 }
  624.                 
  625.                 if( result ) free( result );
  626.                 result = NULL;
  627.             }
  628.         }
  629.         
  630.         if( stem > (struct rxs_stemnode *) NULL )
  631.             free_stemlist( stem );
  632.     }
  633.     
  634. drc_cleanup:
  635.  
  636.     /* Nur RESULT, wenn weder VAR noch STEM */
  637.     
  638.     ReplyRexxCommand( rexxmsg, rc, rc2, result );
  639.             
  640.     /* benutzten Speicher freigeben */
  641.     
  642.     if( result ) free( result );
  643.     FreeArgs( host->rdargs );
  644.     if( cargstr ) free( cargstr );
  645.     if( array ) (rxc->function)( host, (void **) &array, RXIF_FREE );
  646.     if( argb ) free( argb );
  647. }
  648.  
  649.  
  650. void ARexxDispatch( struct RexxHost *host )
  651. {
  652.     struct RexxMsg *rexxmsg;
  653.  
  654.     while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  655.     {
  656.         if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  657.         {
  658.             FreeRexxCommand( rexxmsg );
  659.             --host->replies;
  660.         }
  661.         
  662.         else if( ARG0(rexxmsg) )
  663.         {
  664.             DoRXCommand( host, rexxmsg );
  665.         }
  666.     }
  667. }
  668.  
  669.  
  670. void DoShellCommand( struct RexxHost *host, char *comline, BPTR fhout )
  671. {
  672.     struct rxs_command *rxc;
  673.     char *argb = NULL, *arg;
  674.     
  675.     LONG *array = NULL;
  676.     LONG *argarray;
  677.     LONG *resarray;
  678.     
  679.     struct RDArgs *rdargs = NULL;
  680.     char *cargstr = NULL;
  681.     long rc=10, rc2=0;
  682.     
  683.     rdargs = AllocDosObject( DOS_RDARGS, NULL );
  684.     argb   = malloc( strlen(comline) + 2 );
  685.     
  686.     if( !rdargs || !argb )
  687.     {
  688.         rc2 = ERROR_NO_FREE_STORE;
  689.         goto dsc_cleanup;
  690.     }
  691.     
  692.     /* welches Kommando? */
  693.     
  694.     strcpy( argb, comline );
  695.     strcat( argb, "\n" );
  696.     arg = argb;
  697.     
  698.     if( !( rxc = ParseRXCommand( &arg ) ) )
  699.     {
  700.         if( arg = ExpandRXCommand( host, comline ) )
  701.         {
  702.             free( argb );
  703.             if( !(argb = malloc( strlen(arg) + 2 )) )
  704.             {
  705.                 rc2 = ERROR_NO_FREE_STORE;
  706.                 goto dsc_cleanup;
  707.             }
  708.             
  709.             strcpy( argb, arg );
  710.             strcat( argb, "\n" );
  711.             free( arg );
  712.             arg = argb;
  713.             
  714.             rxc = ParseRXCommand( &arg );
  715.         }
  716.     }
  717.     
  718.     if( !rxc )
  719.     {
  720.         rc2 = ERROR_NOT_IMPLEMENTED;
  721.         goto dsc_cleanup;
  722.     }
  723.     
  724.     if( !(rxc->flags & ARB_CF_ENABLED) )
  725.     {
  726.         rc = -10;
  727.         rc2 = (long) "Command disabled";
  728.         goto dsc_cleanup;
  729.     }
  730.     
  731.     /* Speicher für Argumente etc. holen */
  732.     
  733.     (rxc->function)( host, (void **) &array, RXIF_INIT );
  734.     cargstr = malloc( rxc->args ? 512+strlen(rxc->args) : 512 );
  735.     
  736.     if( !array || !cargstr )
  737.     {
  738.         rc2 = ERROR_NO_FREE_STORE;
  739.         goto dsc_cleanup;
  740.     }
  741.     
  742.     argarray = array + 2;
  743.     resarray = array + rxc->resindex;
  744.     
  745.     /* Argumente parsen */
  746.     
  747.     *cargstr = '\0';
  748.     
  749.     if( rxc->results )
  750.         strcpy( cargstr, "VAR/K,STEM/K" );
  751.     
  752.     if( rxc->args )
  753.     {
  754.         if( *cargstr )
  755.             strcat( cargstr, "," );
  756.         strcat( cargstr, rxc->args );
  757.     }
  758.     
  759.     if( *cargstr )
  760.     {
  761.         rdargs->RDA_Source.CS_Buffer = arg;
  762.         rdargs->RDA_Source.CS_Length = strlen(arg);
  763.         rdargs->RDA_Source.CS_CurChr = 0;
  764.         rdargs->RDA_DAList = NULL;
  765.         rdargs->RDA_Flags  = RDAF_NOPROMPT;
  766.         
  767.         if( !ReadArgs(cargstr, argarray, rdargs) )
  768.         {
  769.             rc = 10;
  770.             rc2 = IoErr();
  771.             goto dsc_cleanup;
  772.         }
  773.     }
  774.     
  775.     /* Funktion aufrufen */
  776.     
  777.     (rxc->function)( host, (void **) &array, RXIF_ACTION );
  778.     
  779.     /* Resultat(e) ausgeben */
  780.     
  781.     if( rxc->results && array[0]==0 && fhout )
  782.     {
  783.         struct rxs_stemnode *stem, *s;
  784.         char *result;
  785.         
  786.         stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  787.         result = CreateVAR( stem );
  788.         
  789.         if( (long) result == -1L )
  790.         {
  791.             if( stem > (struct rxs_stemnode *) NULL )
  792.                 free_stemlist( stem );
  793.             rc2 = ERROR_NO_FREE_STORE;
  794.             goto dsc_cleanup;
  795.         }
  796.         
  797.         if( result )
  798.         {
  799.             if( argarray[0] )
  800.             {
  801.                 /* VAR */
  802.                 FPrintf( fhout, "%s = %s\n", argarray[0], result );
  803.                 free( result );
  804.                 result = NULL;
  805.             }
  806.             
  807.             if( argarray[1] )
  808.             {
  809.                 /* STEM */
  810.                 for( s = stem; s; s = s->succ )
  811.                     FPrintf( fhout, "%s = %s\n", s->name, s->value );
  812.                 if( result ) free( result );
  813.                 result = NULL;
  814.             }
  815.         }
  816.         
  817.         /* Nur RESULT, wenn weder VAR noch STEM sein soll */
  818.         if( result )
  819.         {
  820.             FPrintf( fhout, "%s\n", result );
  821.             free( result );
  822.         }
  823.         
  824.         if( stem > (struct rxs_stemnode *) NULL )
  825.             free_stemlist( stem );
  826.     }
  827.     
  828.     /* Rückgabewert */
  829.  
  830.     rc  = array[0];
  831.     rc2 = array[1];
  832.  
  833. dsc_cleanup:
  834.  
  835.     arg = NULL;
  836.     
  837.     if( rc2 )
  838.     {
  839.         if( !cargstr ) cargstr = malloc( 512 );
  840.         
  841.         if( !cargstr )
  842.         {
  843.             arg = "ERROR: Absolutely out of memory";
  844.         }
  845.         else if( rc > 0 )
  846.         {
  847.             if( Fault( rc2, "ERROR", cargstr, 512 ) )
  848.                 arg = cargstr;
  849.             else
  850.                 arg = "ERROR: Unknown Problem";
  851.         }
  852.         else if( rc < 0 )
  853.         {
  854.             strcpy( cargstr, "ERROR: " );
  855.             strncat( cargstr, (char *) rc2, 500 );
  856.             arg = cargstr;
  857.         }
  858.     }
  859.     
  860.     if( arg ) FPrintf( fhout, "%s\n", arg );
  861.     
  862.     /* benutzten Speicher freigeben */
  863.     
  864.     if( cargstr ) free( cargstr );
  865.     if( array ) (rxc->function)( host, (void **) &array, RXIF_FREE );
  866.     if( argb ) free( argb );
  867.     if( rdargs )
  868.     {
  869.         FreeArgs( rdargs );
  870.         FreeDosObject( DOS_RDARGS, rdargs );
  871.     }
  872. }
  873.  
  874.  
  875. void CommandShell( struct RexxHost *host, BPTR fhin, BPTR fhout, char *prompt )
  876. {
  877.     char comline[512], *s;
  878.     struct RexxMsg *rm;
  879.  
  880.     if( !fhin )
  881.         return;
  882.     
  883.     host->flags |= ARB_HF_CMDSHELL;
  884.     do
  885.     {
  886.         /* Prompt ausgeben */
  887.         
  888.         if( fhout && prompt )
  889.             FPuts( fhout, prompt );
  890.         
  891.         /* Befehl einlesen und abarbeiten */
  892.         
  893.         if( s = FGets(fhin, comline, 512) )
  894.         {
  895.             while( *s==' ' || *s=='\t' ) s++;
  896.             
  897.             if( *s != '\n' )
  898.                 DoShellCommand( host, s, fhout );
  899.         }
  900.         else
  901.         {
  902.             host->flags &= ~ARB_HF_CMDSHELL;
  903.         }
  904.         
  905.         /* Port des Hosts leeren */
  906.         
  907.         while( rm = (struct RexxMsg *) GetMsg(host->port) )
  908.         {
  909.             /* Reply? */
  910.             if( rm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  911.             {
  912.                 FreeRexxCommand( rm );
  913.                 --host->replies;
  914.             }
  915.             
  916.             /* sonst Kommando -> Fehler */
  917.             else
  918.             {
  919.                 ReplyRexxCommand( rm, -20, (long)
  920.                     "CommandShell Port", NULL );
  921.             }
  922.         }
  923.     }
  924.     while( host->flags & ARB_HF_CMDSHELL );
  925. }
  926.  
  927.